{# The assistant's voice, in the one modal: what a live call runs on (where the mount takes calls: ``call_rows``, ``calling``), the voice profiles, each with a preview; switch, make one from the active, or edit one; and how terms are said. ``view`` picks the piece: the composer's chip, the list, one voice's form, or the pronunciation list. Previews play through voice.js's Listen handler ([data-speak]). #} {% from "components/macros/icons.html" import icon %} {% from "components/macros/chat.html" import model_row, voice_chip, speak_button %} {% from "components/macros/form.html" import action, field, text_input, number_input, select, primary_button %} {% from "components/macros/feedback.html" import error_banner, empty_state %} {% from "components/macros/layout.html" import dialog_title %} {% from "components/macros/table.html" import data_table %} {% if view == "chip" %} {{ voice_chip(active, path, calling) }} {% elif view == "list" %} {% if chip_oob %}{{ voice_chip(active, path, calling, oob=True) }}{% endif %}
{% if call_rows is not none %} {{ dialog_title("Calls and voice", "What a live call with " ~ assistant ~ " runs on (a meeting's too), and the voice it speaks in. A pick takes effect on the next call, or the next thing said.") }}

Calls run on

{% if call_rows %} {% else %}

No live model can be reached: a call needs an OpenAI or Google key with a realtime model in the catalog.

{% endif %}

Voice

{% else %} {{ dialog_title("Voice", "How " ~ assistant ~ " hears and speaks. A switch takes effect on the next thing said.") }} {% endif %} {% if voices %} {% else %} {{ empty_state("No voices yet", "The first one is made from .env when the app starts.") }} {% endif %}

How every voice says terms like Traefik. {{ action("Pronunciation", hx_dialog(path ~ "/pronunciation", "data-pronunciations")) }}

{# A new voice starts as a copy of the one in use, then opens to edit. #}
{{ error_banner(errors) }} {{ primary_button("Make", type="submit") }}
{% elif view == "form" %}
{{ dialog_title(voice.name, "In use - saving changes how it sounds now." if voice.is_active else "Not in use - preview it, then Use it from the list.") }} {{ error_banner(errors) }} {% call field("Name") %}{{ text_input("name", values.name, required=True) }}{% endcall %}

Speaks as {{ voice.tts_voice or "the default voice" }}{% if voice.tts_model %} on {{ voice.tts_model }}{% endif %}. Design the voice

{% call field("Hearing model") %}{{ select("stt_model", choices.stt_model, values.stt_model, blank=None, block=True) }}{% endcall %} {% call field("Reply") %}{{ select("reply", choices.reply, values.reply, blank=None, block=True) }}{% endcall %} {% call field("Live: check in after (seconds of quiet, 0 never)") %}{{ number_input("live_idle_seconds", values.live_idle_seconds, min=idle[0], max=idle[1]) }}{% endcall %} {% call field("While it works") %}{{ select("working_sound", choices.working_sound, values.working_sound, blank=None, block=True) }}{% endcall %}
{{ action("Back", hx_dialog(path)) }} {{ speak_button(path ~ "/" ~ voice.id ~ "/preview", "text-aegis-muted hover:text-aegis-text") }} {{ primary_button("Save", type="submit") }}
{% elif view == "said" %}
{{ dialog_title("Pronunciation", "How every voice says these terms, read aloud and on a live call. A change takes effect on the next thing said.") }}
{% call(row) data_table([{"key": "term", "label": "Term"}, {"key": "say", "label": "Said as"}], said, flush=False) %} {% if row.key in saved %} {{ action("Remove", hx_dialog_post(path ~ "/pronunciation/delete"), tone="danger", vals={"term": row.term}) }} {% else %} default {% endif %} {% endcall %}
{# Saving a listed term changes how it is said; a new one joins the list. #}
{{ error_banner(errors) }}
{% call field("Term") %}{{ text_input("term", values.term, placeholder="e.g. Traefik", required=True) }}{% endcall %} {% call field("Said as") %}{{ text_input("say", values.say, placeholder="e.g. traffic", required=True) }}{% endcall %} {% call field("IPA (optional)") %}{{ text_input("ipa", values.ipa, placeholder="e.g. ˈtræfɪk") }}{% endcall %}
{{ action("Back", hx_dialog(path)) }} {{ primary_button("Save", type="submit") }}
{% endif %}